home *** CD-ROM | disk | FTP | other *** search
/ Team Palmtops 7 / Palmtops_numero07.iso / WinCE / SDKWindowsCE / HandHeldPCPro30 / sdk.exe / Jupiter SDK / data1.cab / MFC / src / winctrl2.cpp < prev    next >
Encoding:
C/C++ Source or Header  |  1999-02-19  |  33.4 KB  |  1,338 lines

  1. // This is a part of the Microsoft Foundation Classes C++ library.
  2. // Copyright (C) 1992-1998 Microsoft Corporation
  3. // All rights reserved.
  4. //
  5. // This source code is only intended as a supplement to the
  6. // Microsoft Foundation Classes Reference and related
  7. // electronic documentation provided with the library.
  8. // See these sources for detailed information regarding the
  9. // Microsoft Foundation Classes product.
  10.  
  11. #include "stdafx.h"
  12.  
  13. #ifdef AFX_CMNCTL_SEG
  14. #pragma code_seg(AFX_CMNCTL_SEG)
  15. #endif
  16.  
  17. #ifdef _DEBUG
  18. #undef THIS_FILE
  19. static char THIS_FILE[] = __FILE__;
  20. #endif
  21.  
  22. #define new DEBUG_NEW
  23.  
  24. #if !defined(_WIN32_WCE)
  25. #ifndef _AFX_NO_OLE_SUPPORT
  26. extern "C"
  27. {
  28. HIMAGELIST WINAPI ImageList_Read(LPSTREAM pstm);
  29. BOOL       WINAPI ImageList_Write(HIMAGELIST himl, LPSTREAM pstm);
  30. }
  31. #endif
  32.  
  33. /////////////////////////////////////////////////////////////////////////////
  34. // CDragListBox
  35.  
  36. CDragListBox::~CDragListBox()
  37. {
  38.     DestroyWindow();
  39. }
  40.  
  41. void CDragListBox::PreSubclassWindow()
  42. {
  43.     ASSERT(::IsWindow(m_hWnd));
  44.     ASSERT((GetStyle() & (LBS_MULTIPLESEL|LBS_SORT)) == 0);
  45.     MakeDragList(m_hWnd);
  46. }
  47.  
  48. BOOL CDragListBox::BeginDrag(CPoint pt)
  49. {
  50.     m_nLast = -1;
  51.     DrawInsert(ItemFromPt(pt));
  52.     return TRUE;
  53. }
  54.  
  55. void CDragListBox::CancelDrag(CPoint)
  56. {
  57.     DrawInsert(-1);
  58. }
  59.  
  60. UINT CDragListBox::Dragging(CPoint pt)
  61. {
  62.     int nIndex = ItemFromPt(pt, FALSE); // don't allow scrolling just yet
  63.     DrawInsert(nIndex);
  64.     ItemFromPt(pt);
  65.     return (nIndex == LB_ERR) ? DL_STOPCURSOR : DL_MOVECURSOR;
  66. }
  67.  
  68. void CDragListBox::Dropped(int nSrcIndex, CPoint pt)
  69. {
  70.     ASSERT(!(GetStyle() & (LBS_OWNERDRAWFIXED|LBS_OWNERDRAWVARIABLE)) ||
  71.         (GetStyle() & LBS_HASSTRINGS));
  72.  
  73.     DrawInsert(-1);
  74.     int nDestIndex = ItemFromPt(pt);
  75.  
  76.     if (nSrcIndex == -1 || nDestIndex == -1)
  77.         return;
  78.     if (nDestIndex == nSrcIndex || nDestIndex == nSrcIndex+1)
  79.         return; //didn't move
  80.     CString str;
  81.     DWORD dwData;
  82.     GetText(nSrcIndex, str);
  83.     dwData = GetItemData(nSrcIndex);
  84.     DeleteString(nSrcIndex);
  85.     if (nSrcIndex < nDestIndex)
  86.         nDestIndex--;
  87.     nDestIndex = InsertString(nDestIndex, str);
  88.     SetItemData(nDestIndex, dwData);
  89.     SetCurSel(nDestIndex);
  90. }
  91.  
  92. void CDragListBox::DrawInsert(int nIndex)
  93. {
  94.     if (m_nLast != nIndex)
  95.     {
  96.         DrawSingle(m_nLast);
  97.         DrawSingle(nIndex);
  98.         m_nLast = nIndex;
  99.     }
  100. }
  101.  
  102. void CDragListBox::DrawSingle(int nIndex)
  103. {
  104.     if (nIndex == -1)
  105.         return;
  106.     CBrush* pBrush = CDC::GetHalftoneBrush();
  107.     CRect rect;
  108.     GetClientRect(&rect);
  109.     CRgn rgn;
  110.     rgn.CreateRectRgnIndirect(&rect);
  111.  
  112.     CDC* pDC = GetDC();
  113.     // prevent drawing outside of listbox
  114.     // this can happen at the top of the listbox since the listbox's DC is the
  115.     // parent's DC
  116.     pDC->SelectClipRgn(&rgn);
  117.  
  118.     GetItemRect(nIndex, &rect);
  119.     rect.bottom = rect.top+2;
  120.     rect.top -= 2;
  121.     CBrush* pBrushOld = pDC->SelectObject(pBrush);
  122.     //draw main line
  123.     pDC->PatBlt(rect.left, rect.top, rect.Width(), rect.Height(), PATINVERT);
  124.  
  125.     pDC->SelectObject(pBrushOld);
  126.     ReleaseDC(pDC);
  127. }
  128.  
  129. BOOL CDragListBox::OnChildNotify(UINT nMessage, WPARAM wParam, LPARAM lParam, LRESULT* pResult)
  130. {
  131.     if (nMessage != m_nMsgDragList)
  132.         return CListBox::OnChildNotify(nMessage, wParam, lParam, pResult);
  133.  
  134.     ASSERT(pResult != NULL);
  135.     LPDRAGLISTINFO pInfo = (LPDRAGLISTINFO)lParam;
  136.     ASSERT(pInfo != NULL);
  137.     switch (pInfo->uNotification)
  138.     {
  139.     case DL_BEGINDRAG:
  140.         *pResult = BeginDrag(pInfo->ptCursor);
  141.         break;
  142.     case DL_CANCELDRAG:
  143.         CancelDrag(pInfo->ptCursor);
  144.         break;
  145.     case DL_DRAGGING:
  146.         *pResult = Dragging(pInfo->ptCursor);
  147.         break;
  148.     case DL_DROPPED:
  149.         Dropped(GetCurSel(), pInfo->ptCursor);
  150.         break;
  151.     }
  152.     return TRUE;
  153. }
  154. #endif // _WIN32_WCE
  155.  
  156. #if !defined(_WIN32_WCE_NO_CONTROLBARS)
  157. /////////////////////////////////////////////////////////////////////////////
  158. // CToolBarCtrl
  159.  
  160. BEGIN_MESSAGE_MAP(CToolBarCtrl, CWnd)
  161.     //{{AFX_MSG_MAP(CToolBarCtrl)
  162.     ON_WM_CREATE()
  163.     //}}AFX_MSG_MAP
  164. END_MESSAGE_MAP()
  165.  
  166. BOOL CToolBarCtrl::Create(DWORD dwStyle, const RECT& rect, CWnd* pParentWnd,
  167.     UINT nID)
  168. {
  169.     // initialize common controls
  170.     VERIFY(AfxDeferRegisterClass(AFX_WNDCOMMCTL_BAR_REG));
  171.  
  172.     CWnd* pWnd = this;
  173.     return pWnd->Create(TOOLBARCLASSNAME, NULL, dwStyle, rect, pParentWnd, nID);
  174. }
  175.  
  176. CToolBarCtrl::~CToolBarCtrl()
  177. {
  178.     DestroyWindow();
  179. }
  180.  
  181. int CToolBarCtrl::AddBitmap(int nNumButtons, CBitmap* pBitmap)
  182. {
  183.     ASSERT(::IsWindow(m_hWnd));
  184.     TBADDBITMAP tbab;
  185.     tbab.hInst = NULL;
  186.     tbab.nID = (UINT)pBitmap->GetSafeHandle();
  187.     return (int) ::SendMessage(m_hWnd, TB_ADDBITMAP, (WPARAM)nNumButtons,
  188.         (LPARAM)&tbab);
  189. }
  190.  
  191. int CToolBarCtrl::AddBitmap(int nNumButtons, UINT nBitmapID)
  192. {
  193.     ASSERT(::IsWindow(m_hWnd));
  194.     TBADDBITMAP tbab;
  195.     tbab.hInst = AfxFindResourceHandle((LPCTSTR)nBitmapID, RT_BITMAP);
  196.     ASSERT(tbab.hInst != NULL);
  197.     tbab.nID = nBitmapID;
  198.     return (int) ::SendMessage(m_hWnd, TB_ADDBITMAP, (WPARAM)nNumButtons,
  199.         (LPARAM)&tbab);
  200. }
  201.  
  202. #if !defined(_WIN32_WCE)
  203. void CToolBarCtrl::SaveState(HKEY hKeyRoot, LPCTSTR lpszSubKey,
  204.     LPCTSTR lpszValueName)
  205. {
  206.     ASSERT(::IsWindow(m_hWnd));
  207.     TBSAVEPARAMS tbs;
  208.     tbs.hkr = hKeyRoot;
  209.     tbs.pszSubKey = lpszSubKey;
  210.     tbs.pszValueName = lpszValueName;
  211.     ::SendMessage(m_hWnd, TB_SAVERESTORE, (WPARAM)TRUE, (LPARAM)&tbs);
  212. }
  213.  
  214. void CToolBarCtrl::RestoreState(HKEY hKeyRoot, LPCTSTR lpszSubKey,
  215.     LPCTSTR lpszValueName)
  216. {
  217.     ASSERT(::IsWindow(m_hWnd));
  218.     TBSAVEPARAMS tbs;
  219.     tbs.hkr = hKeyRoot;
  220.     tbs.pszSubKey = lpszSubKey;
  221.     tbs.pszValueName = lpszValueName;
  222.     ::SendMessage(m_hWnd, TB_SAVERESTORE, (WPARAM)FALSE, (LPARAM)&tbs);
  223. }
  224. #endif // _WIN32_WCE
  225.  
  226. int CToolBarCtrl::AddString(UINT nStringID)
  227. {
  228.     ASSERT(::IsWindow(m_hWnd));
  229.     HINSTANCE hInst = AfxFindResourceHandle(MAKEINTRESOURCE((nStringID>>4)+1),
  230.         RT_STRING);
  231.     ASSERT(hInst != NULL);
  232.     return (int)::SendMessage(m_hWnd, TB_ADDSTRING, (WPARAM)hInst, nStringID);
  233. }
  234.  
  235. int CToolBarCtrl::OnCreate(LPCREATESTRUCT lpcs)
  236. {
  237.     if (CWnd::OnCreate(lpcs) == -1)
  238.         return -1;
  239.     SetButtonStructSize(sizeof(TBBUTTON));
  240.     return 0;
  241. }
  242.  
  243. #if !defined(_WIN32_WCE)
  244. HRESULT CToolBarCtrl::GetDropTarget(IDropTarget** ppDropTarget) const
  245. {
  246.     ASSERT(::IsWindow(m_hWnd));
  247.     ASSERT(ppDropTarget);
  248.     return (HRESULT) ::SendMessage(m_hWnd, TB_GETOBJECT, (WPARAM)&IID_IDropTarget, (LPARAM)ppDropTarget);
  249. }
  250. #endif // _WIN32_WCE
  251.  
  252. /////////////////////////////////////////////////////////////////////////////
  253. // CStatusBarCtrl
  254.  
  255. BOOL CStatusBarCtrl::Create(DWORD dwStyle, const RECT& rect, CWnd* pParentWnd,
  256.     UINT nID)
  257. {
  258.     // initialize common controls
  259.     VERIFY(AfxDeferRegisterClass(AFX_WNDCOMMCTL_BAR_REG));
  260.  
  261.     CWnd* pWnd = this;
  262.     return pWnd->Create(STATUSCLASSNAME, NULL, dwStyle, rect, pParentWnd, nID);
  263. }
  264.  
  265. CStatusBarCtrl::~CStatusBarCtrl()
  266. {
  267.     DestroyWindow();
  268. }
  269.  
  270. int CStatusBarCtrl::GetText(LPCTSTR lpszText, int nPane, int* pType) const
  271. {
  272.     ASSERT(::IsWindow(m_hWnd));
  273.     ASSERT(nPane < 256);
  274.     DWORD dw = ::SendMessage(m_hWnd, SB_GETTEXT, (WPARAM)nPane,
  275.         (LPARAM)lpszText);
  276.     if (pType != NULL)
  277.         *pType = HIWORD(dw);
  278.     return LOWORD(dw);
  279. }
  280.  
  281. CString CStatusBarCtrl::GetText(int nPane, int* pType) const
  282. {
  283.     ASSERT(::IsWindow(m_hWnd));
  284.     ASSERT(nPane < 256);
  285.     int nLength = LOWORD(::SendMessage(m_hWnd, SB_GETTEXTLENGTH,
  286.         (WPARAM)nPane, 0L));
  287.     CString str;
  288.     DWORD dw = ::SendMessage(m_hWnd, SB_GETTEXT, (WPARAM)nPane,
  289.         (LPARAM)str.GetBufferSetLength(nLength+1));
  290.     str.ReleaseBuffer();
  291.     if (pType != NULL)
  292.         *pType = HIWORD(dw);
  293.     return str;
  294. }
  295.  
  296. int CStatusBarCtrl::GetTextLength(int nPane, int* pType) const
  297. {
  298.     ASSERT(::IsWindow(m_hWnd));
  299.     ASSERT(nPane < 256);
  300.     DWORD dw = ::SendMessage(m_hWnd, SB_GETTEXTLENGTH, (WPARAM)nPane, 0L);
  301.     if (pType != NULL)
  302.         *pType = HIWORD(dw);
  303.     return LOWORD(dw);
  304. }
  305.  
  306. #if !defined(_WIN32_WCE)
  307. CString CStatusBarCtrl::GetTipText(int nPane) const
  308. {
  309.     ASSERT(::IsWindow(m_hWnd));
  310.     ASSERT(nPane < 256);
  311.     TCHAR buf[256];
  312.     ::SendMessage(m_hWnd, SB_GETTIPTEXT, MAKEWPARAM(nPane, 256), (LPARAM)buf);
  313.     return CString(buf);
  314. }
  315. #endif // _WIN32_WCE
  316.  
  317. BOOL CStatusBarCtrl::GetBorders(int& nHorz, int& nVert, int& nSpacing) const
  318. {
  319.     ASSERT(::IsWindow(m_hWnd));
  320.     int borders[3];
  321.     BOOL bResult = (BOOL)::SendMessage(m_hWnd, SB_GETBORDERS, 0,
  322.         (LPARAM)&borders);
  323.     if (bResult)
  324.     {
  325.         nHorz = borders[0];
  326.         nVert = borders[1];
  327.         nSpacing = borders[2];
  328.     }
  329.     return bResult;
  330. }
  331.  
  332. void CStatusBarCtrl::DrawItem(LPDRAWITEMSTRUCT)
  333. {
  334.     ASSERT(FALSE);  // must override for self draw status bars
  335. }
  336.  
  337. BOOL CStatusBarCtrl::OnChildNotify(UINT message, WPARAM wParam, LPARAM lParam,
  338.     LRESULT* pResult)
  339. {
  340.     if (message != WM_DRAWITEM)
  341.         return CWnd::OnChildNotify(message, wParam, lParam, pResult);
  342.  
  343.     ASSERT(pResult == NULL);       // no return value expected
  344.     UNUSED(pResult); // unused in release builds
  345.  
  346.     DrawItem((LPDRAWITEMSTRUCT)lParam);
  347.     return TRUE;
  348. }
  349. #endif // _WIN32_WCE_NO_CONTROLBARS
  350.  
  351. /////////////////////////////////////////////////////////////////////////////
  352. // CListCtrl
  353.  
  354. BEGIN_MESSAGE_MAP(CListCtrl, CWnd)
  355.     //{{AFX_MSG_MAP(CListCtrl)
  356.     ON_WM_NCDESTROY()
  357.     //}}AFX_MSG_MAP
  358. END_MESSAGE_MAP()
  359.  
  360. BOOL CListCtrl::Create(DWORD dwStyle, const RECT& rect, CWnd* pParentWnd,
  361.     UINT nID)
  362. {
  363.     // initialize common controls
  364.     VERIFY(AfxDeferRegisterClass(AFX_WNDCOMMCTL_LISTVIEW_REG));
  365.  
  366.     CWnd* pWnd = this;
  367.     return pWnd->Create(WC_LISTVIEW, NULL, dwStyle, rect, pParentWnd, nID);
  368. }
  369.  
  370. CListCtrl::~CListCtrl()
  371. {
  372.     DestroyWindow();
  373. }
  374.  
  375. BOOL CListCtrl::GetItemRect(int nItem, LPRECT lpRect, UINT nCode) const
  376. {
  377.     ASSERT(::IsWindow(m_hWnd));
  378.     lpRect->left = nCode;
  379.     return (BOOL) ::SendMessage(m_hWnd, LVM_GETITEMRECT, (WPARAM)nItem,
  380.         (LPARAM)lpRect);
  381. }
  382.  
  383. BOOL CListCtrl::SetItemCountEx(int iCount, DWORD dwFlags /* = LVSICF_NOINVALIDATEALL */)
  384. {
  385.     ASSERT(::IsWindow(m_hWnd));
  386.  
  387.     // can't have dwFlags on a control that isn't virutal
  388.     ASSERT(dwFlags == 0 || (GetStyle() & LVS_OWNERDATA));
  389.  
  390.     return (BOOL) ::SendMessage(m_hWnd, LVM_SETITEMCOUNT, (WPARAM) iCount,
  391.         (LPARAM) dwFlags);
  392. }
  393.  
  394. CSize CListCtrl::SetIconSpacing(int cx, int cy)
  395. {
  396.     ASSERT(::IsWindow(m_hWnd));
  397.     DWORD dwRet = (DWORD) ::SendMessage(m_hWnd, LVM_SETICONSPACING,
  398.         0, (LPARAM) MAKELONG(cx, cy));
  399.  
  400.     return CSize(dwRet);
  401. }
  402.  
  403. CSize CListCtrl::SetIconSpacing(CSize size)
  404. {
  405.     ASSERT(::IsWindow(m_hWnd));
  406.     DWORD dwRet = (DWORD) ::SendMessage(m_hWnd, LVM_SETICONSPACING,
  407.         0, (LPARAM) MAKELONG(size.cx, size.cy));
  408.  
  409.     return CSize(dwRet);
  410. }
  411.  
  412. BOOL CListCtrl::GetSubItemRect(int iItem, int iSubItem, int nArea, CRect& ref)
  413. {
  414.     ASSERT(::IsWindow(m_hWnd));
  415.     ASSERT(nArea == LVIR_BOUNDS || nArea == LVIR_ICON || nArea == LVIR_LABEL);
  416.  
  417.     RECT rect;
  418.     rect.top = iSubItem;
  419.     rect.left = nArea;
  420.     BOOL bRet = (BOOL) ::SendMessage(m_hWnd, LVM_GETSUBITEMRECT,
  421.         iItem, (LPARAM) &rect);
  422.  
  423.     if (bRet)
  424.         ref = rect;
  425.     return bRet;
  426. }
  427.  
  428. int CListCtrl::InsertColumn(int nCol, LPCTSTR lpszColumnHeading, int nFormat,
  429.     int nWidth, int nSubItem)
  430. {
  431.     LVCOLUMN column;
  432.     column.mask = LVCF_TEXT|LVCF_FMT;
  433.     column.pszText = (LPTSTR)lpszColumnHeading;
  434.     column.fmt = nFormat;
  435.     if (nWidth != -1)
  436.     {
  437.         column.mask |= LVCF_WIDTH;
  438.         column.cx = nWidth;
  439.     }
  440.     if (nSubItem != -1)
  441.     {
  442.         column.mask |= LVCF_SUBITEM;
  443.         column.iSubItem = nSubItem;
  444.     }
  445.     return CListCtrl::InsertColumn(nCol, &column);
  446. }
  447.  
  448. int CListCtrl::InsertItem(UINT nMask, int nItem, LPCTSTR lpszItem, UINT nState, UINT nStateMask,
  449.     int nImage, LPARAM lParam)
  450. {
  451.     ASSERT(::IsWindow(m_hWnd));
  452.     LVITEM item;
  453.     item.mask = nMask;
  454.     item.iItem = nItem;
  455.     item.iSubItem = 0;
  456.     item.pszText = (LPTSTR)lpszItem;
  457.     item.state = nState;
  458.     item.stateMask = nStateMask;
  459.     item.iImage = nImage;
  460.     item.lParam = lParam;
  461.     return CListCtrl::InsertItem(&item);
  462. }
  463.  
  464. int CListCtrl::HitTest(CPoint pt, UINT* pFlags) const
  465. {
  466.     ASSERT(::IsWindow(m_hWnd));
  467.     LVHITTESTINFO hti;
  468.     hti.pt = pt;
  469.     int nRes = (int) ::SendMessage(m_hWnd, LVM_HITTEST, 0, (LPARAM)&hti);
  470.     if (pFlags != NULL)
  471.         *pFlags = hti.flags;
  472.     return nRes;
  473. }
  474.  
  475. BOOL CListCtrl::SetItem(int nItem, int nSubItem, UINT nMask, LPCTSTR lpszItem,
  476.     int nImage, UINT nState, UINT nStateMask, LPARAM lParam)
  477. {
  478.     ASSERT(::IsWindow(m_hWnd));
  479.     ASSERT((GetStyle() & LVS_OWNERDATA)==0);
  480.     LVITEM lvi;
  481.     lvi.mask = nMask;
  482.     lvi.iItem = nItem;
  483.     lvi.iSubItem = nSubItem;
  484.     lvi.stateMask = nStateMask;
  485.     lvi.state = nState;
  486.     lvi.pszText = (LPTSTR) lpszItem;
  487.     lvi.iImage = nImage;
  488.     lvi.lParam = lParam;
  489.     return (BOOL) ::SendMessage(m_hWnd, LVM_SETITEM, 0, (LPARAM)&lvi);
  490. }
  491.  
  492. BOOL CListCtrl::SetItemState(int nItem, UINT nState, UINT nStateMask)
  493. {
  494.     ASSERT(::IsWindow(m_hWnd));
  495.     LVITEM lvi;
  496.     lvi.stateMask = nStateMask;
  497.     lvi.state = nState;
  498.     return (BOOL) ::SendMessage(m_hWnd, LVM_SETITEMSTATE, nItem, (LPARAM)&lvi);
  499. }
  500.  
  501. BOOL CListCtrl::SetItemText(int nItem, int nSubItem, LPCTSTR lpszText)
  502. {
  503.     ASSERT(::IsWindow(m_hWnd));
  504.     ASSERT((GetStyle() & LVS_OWNERDATA)==0);
  505.     LVITEM lvi;
  506.     lvi.iSubItem = nSubItem;
  507.     lvi.pszText = (LPTSTR) lpszText;
  508.     return (BOOL) ::SendMessage(m_hWnd, LVM_SETITEMTEXT, nItem, (LPARAM)&lvi);
  509. }
  510.  
  511. CString CListCtrl::GetItemText(int nItem, int nSubItem) const
  512. {
  513.     ASSERT(::IsWindow(m_hWnd));
  514.     LVITEM lvi;
  515.     memset(&lvi, 0, sizeof(LVITEM));
  516.     lvi.iSubItem = nSubItem;
  517.     CString str;
  518.     int nLen = 128;
  519.     int nRes;
  520.     do
  521.     {
  522.         nLen *= 2;
  523.         lvi.cchTextMax = nLen;
  524.         lvi.pszText = str.GetBufferSetLength(nLen);
  525.         nRes  = (int)::SendMessage(m_hWnd, LVM_GETITEMTEXT, (WPARAM)nItem,
  526.             (LPARAM)&lvi);
  527.     } while (nRes == nLen-1);
  528.     str.ReleaseBuffer();
  529.     return str;
  530. }
  531.  
  532. int CListCtrl::GetItemText(int nItem, int nSubItem, LPTSTR lpszText, int nLen) const
  533. {
  534.     ASSERT(::IsWindow(m_hWnd));
  535.     LVITEM lvi;
  536.     memset(&lvi, 0, sizeof(LVITEM));
  537.     lvi.iSubItem = nSubItem;
  538.     lvi.cchTextMax = nLen;
  539.     lvi.pszText = lpszText;
  540.     return (int)::SendMessage(m_hWnd, LVM_GETITEMTEXT, (WPARAM)nItem,
  541.         (LPARAM)&lvi);
  542. }
  543.  
  544. DWORD CListCtrl::GetItemData(int nItem) const
  545. {
  546.     ASSERT(::IsWindow(m_hWnd));
  547.     LVITEM lvi;
  548.     memset(&lvi, 0, sizeof(LVITEM));
  549.     lvi.iItem = nItem;
  550.     lvi.mask = LVIF_PARAM;
  551.     VERIFY(::SendMessage(m_hWnd, LVM_GETITEM, 0, (LPARAM)&lvi));
  552.     return (DWORD)lvi.lParam;
  553. }
  554.  
  555. void CListCtrl::DrawItem(LPDRAWITEMSTRUCT)
  556. {
  557.     ASSERT(FALSE);
  558. }
  559.  
  560. BOOL CListCtrl::OnChildNotify(UINT message, WPARAM wParam, LPARAM lParam,
  561.     LRESULT* pResult)
  562. {
  563.     if (message != WM_DRAWITEM)
  564.         return CWnd::OnChildNotify(message, wParam, lParam, pResult);
  565.  
  566.     ASSERT(pResult == NULL);       // no return value expected
  567.     UNUSED(pResult); // unused in release builds
  568.  
  569.     DrawItem((LPDRAWITEMSTRUCT)lParam);
  570.     return TRUE;
  571. }
  572.  
  573. void CListCtrl::RemoveImageList(int nImageList)
  574. {
  575.     HIMAGELIST h = (HIMAGELIST)SendMessage(LVM_GETIMAGELIST,
  576.         (WPARAM)nImageList);
  577.     if (CImageList::FromHandlePermanent(h) != NULL)
  578.         SendMessage(LVM_SETIMAGELIST, (WPARAM)nImageList, NULL);
  579. }
  580.  
  581. void CListCtrl::OnNcDestroy()
  582. {
  583.     RemoveImageList(LVSIL_NORMAL);
  584.     RemoveImageList(LVSIL_SMALL);
  585.     RemoveImageList(LVSIL_STATE);
  586.  
  587.     CWnd::OnNcDestroy();
  588. }
  589.  
  590. #if !defined(_WIN32_WCE)
  591. CImageList* CListCtrl::CreateDragImage(int nItem, LPPOINT lpPoint)
  592. {
  593.     ASSERT(::IsWindow(m_hWnd));
  594.  
  595.     HIMAGELIST hImageList = (HIMAGELIST)::SendMessage(m_hWnd,
  596.         LVM_CREATEDRAGIMAGE, nItem, (LPARAM)lpPoint);
  597.     if (hImageList == NULL)
  598.         return NULL;
  599.  
  600.     CImageList* pImageList = new CImageList;
  601.     VERIFY(pImageList->Attach(hImageList));
  602.     return pImageList;
  603. }
  604. #endif // _WIN32_WCE
  605.  
  606. /////////////////////////////////////////////////////////////////////////////
  607. // CTreeCtrl
  608.  
  609. BEGIN_MESSAGE_MAP(CTreeCtrl, CWnd)
  610.     //{{AFX_MSG_MAP(CTreeCtrl)
  611.     ON_WM_DESTROY()
  612.     //}}AFX_MSG_MAP
  613. END_MESSAGE_MAP()
  614.  
  615. BOOL CTreeCtrl::Create(DWORD dwStyle, const RECT& rect, CWnd* pParentWnd,
  616.     UINT nID)
  617. {
  618.     // initialize common controls
  619.     VERIFY(AfxDeferRegisterClass(AFX_WNDCOMMCTL_TREEVIEW_REG));
  620.  
  621.     CWnd* pWnd = this;
  622.     return pWnd->Create(WC_TREEVIEW, NULL, dwStyle, rect, pParentWnd, nID);
  623. }
  624.  
  625. CTreeCtrl::~CTreeCtrl()
  626. {
  627.     DestroyWindow();
  628. }
  629.  
  630. BOOL CTreeCtrl::GetItemRect(HTREEITEM hItem, LPRECT lpRect, BOOL bTextOnly) const
  631. {
  632.     ASSERT(::IsWindow(m_hWnd));
  633.     *(HTREEITEM*)lpRect = hItem;
  634.     return (BOOL)::SendMessage(m_hWnd, TVM_GETITEMRECT, (WPARAM)bTextOnly,
  635.         (LPARAM)lpRect);
  636. }
  637.  
  638. CString CTreeCtrl::GetItemText(HTREEITEM hItem) const
  639. {
  640.     ASSERT(::IsWindow(m_hWnd));
  641.     TVITEM item;
  642.     item.hItem = hItem;
  643.     item.mask = TVIF_TEXT;
  644.     CString str;
  645.     int nLen = 128;
  646.     int nRes;
  647.     do
  648.     {
  649.         nLen *= 2;
  650.         item.pszText = str.GetBufferSetLength(nLen);
  651.         item.cchTextMax = nLen;
  652.         ::SendMessage(m_hWnd, TVM_GETITEM, 0, (LPARAM)&item);
  653.         nRes = lstrlen(item.pszText);
  654.     } while (nRes == nLen-1);
  655.     str.ReleaseBuffer();
  656.     return str;
  657. }
  658.  
  659. BOOL CTreeCtrl::GetItemImage(HTREEITEM hItem, int& nImage, int& nSelectedImage) const
  660. {
  661.     ASSERT(::IsWindow(m_hWnd));
  662.     TVITEM item;
  663.     item.hItem = hItem;
  664.     item.mask = TVIF_IMAGE|TVIF_SELECTEDIMAGE;
  665.     BOOL bRes = (BOOL)::SendMessage(m_hWnd, TVM_GETITEM, 0, (LPARAM)&item);
  666.     if (bRes)
  667.     {
  668.         nImage = item.iImage;
  669.         nSelectedImage = item.iSelectedImage;
  670.     }
  671.     return bRes;
  672. }
  673.  
  674. UINT CTreeCtrl::GetItemState(HTREEITEM hItem, UINT nStateMask) const
  675. {
  676.     ASSERT(::IsWindow(m_hWnd));
  677.     TVITEM item;
  678.     item.hItem = hItem;
  679.     item.mask = TVIF_STATE;
  680.     item.stateMask = nStateMask;
  681.     item.state = 0;
  682.     VERIFY(::SendMessage(m_hWnd, TVM_GETITEM, 0, (LPARAM)&item));
  683.     return item.state;
  684. }
  685.  
  686. DWORD CTreeCtrl::GetItemData(HTREEITEM hItem) const
  687. {
  688.     ASSERT(::IsWindow(m_hWnd));
  689.     TVITEM item;
  690.     item.hItem = hItem;
  691.     item.mask = TVIF_PARAM;
  692.     VERIFY(::SendMessage(m_hWnd, TVM_GETITEM, 0, (LPARAM)&item));
  693.     return (DWORD)item.lParam;
  694. }
  695.  
  696. BOOL CTreeCtrl::ItemHasChildren(HTREEITEM hItem) const
  697. {
  698.     ASSERT(::IsWindow(m_hWnd));
  699.     TVITEM item;
  700.     item.hItem = hItem;
  701.     item.mask = TVIF_CHILDREN;
  702.     ::SendMessage(m_hWnd, TVM_GETITEM, 0, (LPARAM)&item);
  703.     return item.cChildren;
  704. }
  705.  
  706. BOOL CTreeCtrl::SetItem(HTREEITEM hItem, UINT nMask, LPCTSTR lpszItem, int nImage,
  707.     int nSelectedImage, UINT nState, UINT nStateMask, LPARAM lParam)
  708. {
  709.     ASSERT(::IsWindow(m_hWnd));
  710.     TVITEM item;
  711.     item.hItem = hItem;
  712.     item.mask = nMask;
  713.     item.pszText = (LPTSTR) lpszItem;
  714.     item.iImage = nImage;
  715.     item.iSelectedImage = nSelectedImage;
  716.     item.state = nState;
  717.     item.stateMask = nStateMask;
  718.     item.lParam = lParam;
  719.     return (BOOL)::SendMessage(m_hWnd, TVM_SETITEM, 0, (LPARAM)&item);
  720. }
  721.  
  722. HTREEITEM CTreeCtrl::InsertItem(UINT nMask, LPCTSTR lpszItem, int nImage,
  723.     int nSelectedImage, UINT nState, UINT nStateMask, LPARAM lParam,
  724.     HTREEITEM hParent, HTREEITEM hInsertAfter)
  725. {
  726.     ASSERT(::IsWindow(m_hWnd));
  727.     TVINSERTSTRUCT tvis;
  728.     tvis.hParent = hParent;
  729.     tvis.hInsertAfter = hInsertAfter;
  730.     tvis.item.mask = nMask;
  731.     tvis.item.pszText = (LPTSTR) lpszItem;
  732.     tvis.item.iImage = nImage;
  733.     tvis.item.iSelectedImage = nSelectedImage;
  734.     tvis.item.state = nState;
  735.     tvis.item.stateMask = nStateMask;
  736.     tvis.item.lParam = lParam;
  737.     return (HTREEITEM)::SendMessage(m_hWnd, TVM_INSERTITEM, 0, (LPARAM)&tvis);
  738. }
  739.  
  740. HTREEITEM CTreeCtrl::HitTest(CPoint pt, UINT* pFlags) const
  741. {
  742.     ASSERT(::IsWindow(m_hWnd));
  743.     TVHITTESTINFO hti;
  744.     hti.pt = pt;
  745.     HTREEITEM h = (HTREEITEM)::SendMessage(m_hWnd, TVM_HITTEST, 0,
  746.         (LPARAM)&hti);
  747.     if (pFlags != NULL)
  748.         *pFlags = hti.flags;
  749.     return h;
  750. }
  751.  
  752. void CTreeCtrl::RemoveImageList(int nImageList)
  753. {
  754.     HIMAGELIST h = (HIMAGELIST)SendMessage(TVM_GETIMAGELIST,
  755.         (WPARAM)nImageList);
  756.     if (CImageList::FromHandlePermanent(h) != NULL)
  757.         SendMessage(TVM_SETIMAGELIST, (WPARAM)nImageList, NULL);
  758. }
  759.  
  760. void CTreeCtrl::OnDestroy()
  761. {
  762.     RemoveImageList(LVSIL_NORMAL);
  763.     RemoveImageList(LVSIL_STATE);
  764.  
  765.     CWnd::OnDestroy();
  766. }
  767.  
  768. CImageList* CTreeCtrl::CreateDragImage(HTREEITEM hItem)
  769. {
  770.     ASSERT(::IsWindow(m_hWnd));
  771.  
  772.     HIMAGELIST hImageList = (HIMAGELIST)::SendMessage(m_hWnd,
  773.         TVM_CREATEDRAGIMAGE, 0, (LPARAM)hItem);
  774.     if (hImageList == NULL)
  775.         return NULL;
  776.  
  777.     CImageList* pImageList = new CImageList;
  778.     VERIFY(pImageList->Attach(hImageList));
  779.     return pImageList;
  780. }
  781.  
  782. BOOL CTreeCtrl::GetCheck(HTREEITEM hItem) const
  783. {
  784.     ASSERT(::IsWindow(m_hWnd));
  785.     TVITEM item;
  786.     item.mask = TVIF_HANDLE | TVIF_STATE;
  787.     item.hItem = hItem;
  788.     item.stateMask = TVIS_STATEIMAGEMASK;
  789.     VERIFY(::SendMessage(m_hWnd, TVM_GETITEM, 0, (LPARAM)&item));
  790.     // Return zero if it's not checked, or nonzero otherwise.
  791.     return ((BOOL)(item.state >> 12) -1);
  792. }
  793.  
  794. BOOL CTreeCtrl::SetCheck(HTREEITEM hItem, BOOL fCheck)
  795. {
  796.     ASSERT(::IsWindow(m_hWnd));
  797.     TVITEM item;
  798.     item.mask = TVIF_HANDLE | TVIF_STATE;
  799.     item.hItem = hItem;
  800.     item.stateMask = TVIS_STATEIMAGEMASK;
  801.  
  802.     /*
  803.     Since state images are one-based, 1 in this macro turns the check off, and
  804.     2 turns it on.
  805.     */
  806.     item.state = INDEXTOSTATEIMAGEMASK((fCheck ? 2 : 1));
  807.  
  808.     return (BOOL)::SendMessage(m_hWnd, TVM_SETITEM, 0, (LPARAM)&item);
  809. }
  810.  
  811. /////////////////////////////////////////////////////////////////////////////
  812. // CSpinButtonCtrl
  813.  
  814. BOOL CSpinButtonCtrl::Create(DWORD dwStyle, const RECT& rect, CWnd* pParentWnd,
  815.     UINT nID)
  816. {
  817.     // initialize common controls
  818.     VERIFY(AfxDeferRegisterClass(AFX_WNDCOMMCTL_UPDOWN_REG));
  819.  
  820.     CWnd* pWnd = this;
  821.     return pWnd->Create(UPDOWN_CLASS, NULL, dwStyle, rect, pParentWnd, nID);
  822. }
  823.  
  824. CSpinButtonCtrl::~CSpinButtonCtrl()
  825. {
  826.     DestroyWindow();
  827. }
  828.  
  829. void CSpinButtonCtrl::GetRange(int &lower, int& upper) const
  830. {
  831.     ASSERT(::IsWindow(m_hWnd));
  832.     DWORD dw = ::SendMessage(m_hWnd, UDM_GETRANGE, 0, 0l);
  833.     lower = (int)(short)HIWORD(dw);
  834.     upper = (int)(short)LOWORD(dw);
  835. }
  836.  
  837. /////////////////////////////////////////////////////////////////////////////
  838. // CSliderCtrl
  839.  
  840. BOOL CSliderCtrl::Create(DWORD dwStyle, const RECT& rect, CWnd* pParentWnd,
  841.     UINT nID)
  842. {
  843.     // initialize common controls
  844.     VERIFY(AfxDeferRegisterClass(AFX_WNDCOMMCTL_BAR_REG));
  845.  
  846.     CWnd* pWnd = this;
  847.     return pWnd->Create(TRACKBAR_CLASS, NULL, dwStyle, rect, pParentWnd, nID);
  848. }
  849.  
  850. CSliderCtrl::~CSliderCtrl()
  851. {
  852.     DestroyWindow();
  853. }
  854.  
  855. void CSliderCtrl::GetRange(int& nMin, int& nMax) const
  856. {
  857.     ASSERT(::IsWindow(m_hWnd));
  858.     nMin = GetRangeMin();
  859.     nMax = GetRangeMax();
  860. }
  861.  
  862. void CSliderCtrl::SetRange(int nMin, int nMax, BOOL bRedraw)
  863. {
  864.     SetRangeMin(nMin, bRedraw);
  865.     SetRangeMax(nMax, bRedraw);
  866. }
  867.  
  868. void CSliderCtrl::GetSelection(int& nMin, int& nMax) const
  869. {
  870.     ASSERT(::IsWindow(m_hWnd));
  871.     nMin = ::SendMessage(m_hWnd, TBM_GETSELSTART, 0, 0L);
  872.     nMax = ::SendMessage(m_hWnd, TBM_GETSELEND, 0, 0L);
  873. }
  874.  
  875. void CSliderCtrl::SetSelection(int nMin, int nMax)
  876. {
  877.     ASSERT(::IsWindow(m_hWnd));
  878.     ::SendMessage(m_hWnd, TBM_SETSELSTART, 0, (LPARAM)nMin);
  879.     ::SendMessage(m_hWnd, TBM_SETSELEND, 0, (LPARAM)nMax);
  880. }
  881.  
  882. /////////////////////////////////////////////////////////////////////////////
  883. // CProgressCtrl
  884.  
  885. BOOL CProgressCtrl::Create(DWORD dwStyle, const RECT& rect, CWnd* pParentWnd,
  886.     UINT nID)
  887. {
  888.     // initialize common controls
  889.     VERIFY(AfxDeferRegisterClass(AFX_WNDCOMMCTL_PROGRESS_REG));
  890.  
  891.     CWnd* pWnd = this;
  892.     return pWnd->Create(PROGRESS_CLASS, NULL, dwStyle, rect, pParentWnd, nID);
  893. }
  894.  
  895. CProgressCtrl::~CProgressCtrl()
  896. {
  897.     DestroyWindow();
  898. }
  899.  
  900. /////////////////////////////////////////////////////////////////////////////
  901. // CHeaderCtrl
  902.  
  903. BOOL CHeaderCtrl::Create(DWORD dwStyle, const RECT& rect, CWnd* pParentWnd,
  904.     UINT nID)
  905. {
  906.     // initialize common controls
  907.     VERIFY(AfxDeferRegisterClass(AFX_WNDCOMMCTL_LISTVIEW_REG));
  908.  
  909.     CWnd* pWnd = this;
  910.     return pWnd->Create(WC_HEADER, NULL, dwStyle, rect, pParentWnd, nID);
  911. }
  912.  
  913. CHeaderCtrl::~CHeaderCtrl()
  914. {
  915.     DestroyWindow();
  916. }
  917.  
  918. void CHeaderCtrl::DrawItem(LPDRAWITEMSTRUCT)
  919. {
  920.     ASSERT(FALSE);  // must override for self draw header controls
  921. }
  922.  
  923. BOOL CHeaderCtrl::OnChildNotify(UINT message, WPARAM wParam, LPARAM lParam,
  924.     LRESULT* pResult)
  925. {
  926.     if (message != WM_DRAWITEM)
  927.         return CWnd::OnChildNotify(message, wParam, lParam, pResult);
  928.  
  929.     ASSERT(pResult == NULL);       // no return value expected
  930.     UNUSED(pResult); // unused in release builds
  931.  
  932.     DrawItem((LPDRAWITEMSTRUCT)lParam);
  933.     return TRUE;
  934. }
  935.  
  936. #if !defined(_WIN32_WCE)
  937. /////////////////////////////////////////////////////////////////////////////
  938. // CHotKeyCtrl
  939.  
  940. BOOL CHotKeyCtrl::Create(DWORD dwStyle, const RECT& rect, CWnd* pParentWnd,
  941.     UINT nID)
  942. {
  943.     // initialize common controls
  944.     VERIFY(AfxDeferRegisterClass(AFX_WNDCOMMCTL_HOTKEY_REG));
  945.  
  946.     CWnd* pWnd = this;
  947.     return pWnd->Create(HOTKEY_CLASS, NULL, dwStyle, rect, pParentWnd, nID);
  948. }
  949.  
  950. CHotKeyCtrl::~CHotKeyCtrl()
  951. {
  952.     DestroyWindow();
  953. }
  954.  
  955. void CHotKeyCtrl::GetHotKey(WORD &wVirtualKeyCode, WORD &wModifiers) const
  956. {
  957.     ASSERT(::IsWindow(m_hWnd));
  958.     DWORD dw = ::SendMessage(m_hWnd, HKM_GETHOTKEY, 0, 0L);
  959.     wVirtualKeyCode = LOBYTE(LOWORD(dw));
  960.     wModifiers = HIBYTE(LOWORD(dw));
  961. }
  962. #endif // _WIN32_WCE
  963.  
  964. /////////////////////////////////////////////////////////////////////////////
  965. // CTabCtrl
  966.  
  967. BEGIN_MESSAGE_MAP(CTabCtrl, CWnd)
  968.     //{{AFX_MSG_MAP(CTabCtrl)
  969.     ON_WM_DESTROY()
  970.     //}}AFX_MSG_MAP
  971. END_MESSAGE_MAP()
  972.  
  973. BOOL CTabCtrl::Create(DWORD dwStyle, const RECT& rect, CWnd* pParentWnd,
  974.     UINT nID)
  975. {
  976.     // initialize common controls
  977.     VERIFY(AfxDeferRegisterClass(AFX_WNDCOMMCTL_TAB_REG));
  978.  
  979.     CWnd* pWnd = this;
  980.     return pWnd->Create(WC_TABCONTROL, NULL, dwStyle, rect, pParentWnd, nID);
  981. }
  982.  
  983. CTabCtrl::~CTabCtrl()
  984. {
  985.     DestroyWindow();
  986. }
  987.  
  988. void CTabCtrl::DrawItem(LPDRAWITEMSTRUCT)
  989. {
  990.     ASSERT(FALSE);  // must override for self draw tab controls
  991. }
  992.  
  993. BOOL CTabCtrl::OnChildNotify(UINT message, WPARAM wParam, LPARAM lParam,
  994.     LRESULT* pResult)
  995. {
  996.     if (message != WM_DRAWITEM)
  997.         return CWnd::OnChildNotify(message, wParam, lParam, pResult);
  998.  
  999.     ASSERT(pResult == NULL);       // no return value expected
  1000.     UNUSED(pResult); // unused in release builds
  1001.  
  1002.     DrawItem((LPDRAWITEMSTRUCT)lParam);
  1003.     return TRUE;
  1004. }
  1005.  
  1006. void CTabCtrl::OnDestroy()
  1007. {
  1008.     HIMAGELIST h = (HIMAGELIST)SendMessage(TCM_GETIMAGELIST);
  1009.     if (CImageList::FromHandlePermanent(h) != NULL)
  1010.         SendMessage(TCM_SETIMAGELIST, NULL, NULL);
  1011.  
  1012.     CWnd::OnDestroy();
  1013. }
  1014.  
  1015. DWORD CTabCtrl::GetItemState(int nItem, DWORD dwMask) const
  1016. {
  1017.     ASSERT(::IsWindow(m_hWnd));
  1018.  
  1019.     TCITEM item;
  1020.     item.mask = TCIF_STATE;
  1021.     item.dwStateMask = dwMask;
  1022.     VERIFY(::SendMessage(m_hWnd, TCM_GETITEM, (WPARAM)nItem, (LPARAM)&item));
  1023.  
  1024.     return item.dwState;
  1025. }
  1026.  
  1027. BOOL CTabCtrl::SetItemState(int nItem, DWORD dwMask, DWORD dwState)
  1028. {
  1029.     ASSERT(::IsWindow(m_hWnd));
  1030.  
  1031.     TCITEM item;
  1032.     item.mask = TCIF_STATE;
  1033.     item.dwState = dwState;
  1034.     item.dwStateMask = dwMask;
  1035.  
  1036.     return (BOOL) ::SendMessage(m_hWnd, TCM_SETITEM,
  1037.         (WPARAM) nItem, (LPARAM) &item);
  1038. }
  1039.  
  1040. BOOL CTabCtrl::InsertItem(UINT nMask, int nItem, LPCTSTR lpszItem,
  1041.     int nImage, LPARAM lParam)
  1042. {
  1043.     ASSERT(::IsWindow(m_hWnd));
  1044.  
  1045.     TCITEM item;
  1046.     item.mask = nMask;
  1047.     item.iImage = nImage;
  1048.     item.lParam = lParam;
  1049.     item.pszText = (LPTSTR) lpszItem;
  1050.  
  1051.     return (BOOL) ::SendMessage(m_hWnd, TCM_INSERTITEM, nItem, (LPARAM) &item);
  1052. }
  1053.  
  1054. BOOL CTabCtrl::InsertItem(UINT nMask, int nItem, LPCTSTR lpszItem,
  1055.     int nImage, LPARAM lParam, DWORD dwState, DWORD dwStateMask)
  1056. {
  1057.     ASSERT(::IsWindow(m_hWnd));
  1058.  
  1059.     TCITEM item;
  1060.     item.mask = nMask;
  1061.     item.iImage = nImage;
  1062.     item.lParam = lParam;
  1063.     item.pszText = (LPTSTR) lpszItem;
  1064.     item.dwState = dwState;
  1065.     item.dwStateMask = dwStateMask;
  1066.  
  1067.     return (BOOL) ::SendMessage(m_hWnd, TCM_INSERTITEM, nItem, (LPARAM) &item);
  1068. }
  1069.  
  1070.  
  1071. #if !defined(_WIN32_WCE)
  1072. /////////////////////////////////////////////////////////////////////////////
  1073. // CAnimateCtrl
  1074.  
  1075. BOOL CAnimateCtrl::Create(DWORD dwStyle, const RECT& rect,
  1076.     CWnd* pParentWnd, UINT nID)
  1077. {
  1078.     // initialize common controls
  1079.     VERIFY(AfxDeferRegisterClass(AFX_WNDCOMMCTL_ANIMATE_REG));
  1080.  
  1081.     CWnd* pWnd = this;
  1082.     return pWnd->Create(ANIMATE_CLASS, NULL, dwStyle, rect, pParentWnd, nID);
  1083. }
  1084.  
  1085. CAnimateCtrl::~CAnimateCtrl()
  1086. {
  1087.     DestroyWindow();
  1088. }
  1089. #endif // _WIN32_WCE
  1090.  
  1091. #ifndef _AFX_NO_RICHEDIT_SUPPORT
  1092.  
  1093. /////////////////////////////////////////////////////////////////////////////
  1094. // CRichEdit
  1095.  
  1096. CRichEditCtrl::~CRichEditCtrl()
  1097. {
  1098.     DestroyWindow();
  1099. }
  1100.  
  1101. #endif //!_AFX_NO_RICHEDIT_SUPPORT
  1102.  
  1103. /////////////////////////////////////////////////////////////////////////////
  1104. // CImageList
  1105.  
  1106. #if !defined(_WIN32_WCE)
  1107. #include "fixalloc.h"
  1108.  
  1109. class CTempImageList : public CImageList
  1110. {
  1111.     DECLARE_DYNCREATE(CTempImageList)
  1112.     DECLARE_FIXED_ALLOC(CTempImageList);
  1113. };
  1114. #endif // _WIN32_WCE
  1115.  
  1116. CHandleMap* PASCAL afxMapHIMAGELIST(BOOL bCreate)
  1117. {
  1118.     AFX_MODULE_THREAD_STATE* pState = AfxGetModuleThreadState();
  1119.     if (pState->m_pmapHIMAGELIST == NULL && bCreate)
  1120.     {
  1121.         BOOL bEnable = AfxEnableMemoryTracking(FALSE);
  1122. #ifndef _AFX_PORTABLE
  1123.         _PNH pnhOldHandler = AfxSetNewHandler(&AfxCriticalNewHandler);
  1124. #endif
  1125.         pState->m_pmapHIMAGELIST = new CHandleMap(WCE_IF(RUNTIME_CLASS(CImageList),RUNTIME_CLASS(CTempImageList)),
  1126.             offsetof(CImageList, m_hImageList));
  1127.  
  1128. #ifndef _AFX_PORTABLE
  1129.         AfxSetNewHandler(pnhOldHandler);
  1130. #endif
  1131.         AfxEnableMemoryTracking(bEnable);
  1132.     }
  1133.     return pState->m_pmapHIMAGELIST;
  1134. }
  1135.  
  1136. CImageList::CImageList()
  1137. {
  1138.     m_hImageList = NULL;
  1139. }
  1140.  
  1141. CImageList::~CImageList()
  1142. {
  1143.     DeleteImageList();
  1144. }
  1145.  
  1146. HIMAGELIST CImageList::Detach()
  1147. {
  1148.     HIMAGELIST hImageList = m_hImageList;
  1149.     if (hImageList != NULL)
  1150.     {
  1151.         CHandleMap* pMap = afxMapHIMAGELIST();
  1152.         if (pMap != NULL)
  1153.             pMap->RemoveHandle(m_hImageList);
  1154.     }
  1155.  
  1156.     m_hImageList = NULL;
  1157.     return hImageList;
  1158. }
  1159.  
  1160. BOOL CImageList::DeleteImageList()
  1161. {
  1162.     if (m_hImageList == NULL)
  1163.         return FALSE;
  1164.     return ImageList_Destroy(Detach());
  1165. }
  1166.  
  1167. CImageList* PASCAL CImageList::FromHandle(HIMAGELIST h)
  1168. {
  1169.     CHandleMap* pMap = afxMapHIMAGELIST(TRUE);
  1170.     ASSERT(pMap != NULL);
  1171.     CImageList* pImageList = (CImageList*)pMap->FromHandle(h);
  1172.     ASSERT(pImageList == NULL || pImageList->m_hImageList == h);
  1173.     return pImageList;
  1174. }
  1175.  
  1176. CImageList* PASCAL CImageList::FromHandlePermanent(HIMAGELIST h)
  1177. {
  1178.     CHandleMap* pMap = afxMapHIMAGELIST();
  1179.     CImageList* pImageList = NULL;
  1180.     if (pMap != NULL)
  1181.     {
  1182.         // only look in the permanent map - does no allocations
  1183.         pImageList = (CImageList*)pMap->LookupPermanent(h);
  1184.         ASSERT(pImageList == NULL || pImageList->m_hImageList == h);
  1185.     }
  1186.     return pImageList;
  1187. }
  1188.  
  1189. BOOL CImageList::Create(int cx, int cy, UINT nFlags, int nInitial, int nGrow)
  1190. {
  1191.     return Attach(ImageList_Create(cx, cy, nFlags, nInitial, nGrow));
  1192. }
  1193.  
  1194. BOOL CImageList::Create(UINT nBitmapID, int cx, int nGrow, COLORREF crMask)
  1195. {
  1196.     ASSERT(HIWORD(nBitmapID) == 0);
  1197.     HINSTANCE hInst = AfxFindResourceHandle((LPCTSTR)nBitmapID, RT_BITMAP);
  1198.     ASSERT(hInst != NULL);
  1199.     return Attach(ImageList_LoadBitmap(hInst, 
  1200.         (LPCTSTR)nBitmapID, cx, nGrow, crMask));
  1201. }
  1202.  
  1203. BOOL CImageList::Create(LPCTSTR lpszBitmapID, int cx, int nGrow,
  1204.     COLORREF crMask)
  1205. {
  1206.     HINSTANCE hInst = AfxFindResourceHandle(lpszBitmapID, RT_BITMAP);
  1207.     ASSERT(hInst != NULL);
  1208.     return Attach(ImageList_LoadBitmap(hInst, lpszBitmapID, cx, nGrow, crMask));
  1209. }
  1210.  
  1211. BOOL CImageList::Create(CImageList& imagelist1, int nImage1,
  1212.     CImageList& imagelist2, int nImage2, int dx, int dy)
  1213. {
  1214.     return Attach(ImageList_Merge(imagelist1.m_hImageList, nImage1,
  1215.         imagelist2.m_hImageList, nImage2, dx, dy));
  1216. }
  1217.  
  1218. BOOL CImageList::Attach(HIMAGELIST hImageList)
  1219. {
  1220.     ASSERT(m_hImageList == NULL);      // only attach once, detach on destroy
  1221.     ASSERT(FromHandlePermanent(hImageList) == NULL);
  1222.  
  1223.     if (hImageList == NULL)
  1224.         return FALSE;
  1225.  
  1226.     CHandleMap* pMap = afxMapHIMAGELIST(TRUE);
  1227.     ASSERT(pMap != NULL);
  1228.  
  1229.     pMap->SetPermanent(m_hImageList = hImageList, this);
  1230.     return TRUE;
  1231. }
  1232.  
  1233. #if !defined(_WIN32_WCE)
  1234. #ifndef _AFX_NO_OLE_SUPPORT
  1235. BOOL CImageList::Read(CArchive* pArchive)
  1236. {
  1237.     ASSERT(m_hImageList == NULL);
  1238.     ASSERT(pArchive != NULL);
  1239.     ASSERT(pArchive->IsLoading());
  1240.     CArchiveStream arcstream(pArchive);
  1241.  
  1242.     m_hImageList = ImageList_Read(&arcstream);
  1243.     return (m_hImageList != NULL);
  1244. }
  1245.  
  1246. BOOL CImageList::Write(CArchive* pArchive)
  1247. {
  1248.     ASSERT(m_hImageList != NULL);
  1249.     ASSERT(pArchive != NULL);
  1250.     ASSERT(pArchive->IsStoring());
  1251.     CArchiveStream arcstream(pArchive);
  1252.     return ImageList_Write(m_hImageList, &arcstream);
  1253. }
  1254. #endif //_AFX_NO_OLE_SUPPORT
  1255. #endif // _WIN32_WCE
  1256.  
  1257. #ifdef _DEBUG
  1258. void CImageList::Dump(CDumpContext& dc) const
  1259. {
  1260.     CObject::Dump(dc);
  1261.  
  1262.     dc << "m_hImageList = " << (UINT)m_hImageList;
  1263.     dc << "\n";
  1264. }
  1265.  
  1266. void CImageList::AssertValid() const
  1267. {
  1268.     CObject::AssertValid();
  1269.     if (m_hImageList == NULL)
  1270.         return;
  1271.     // should also be in the permanent or temporary handle map
  1272.     CObject* p;
  1273.  
  1274.     CHandleMap* pMap = afxMapHIMAGELIST();
  1275.     ASSERT(pMap != NULL);
  1276.  
  1277.     ASSERT((p = pMap->LookupPermanent(m_hImageList)) != NULL ||
  1278.         (p = pMap->LookupTemporary(m_hImageList)) != NULL);
  1279.     ASSERT((CImageList*)p == this);   // must be us
  1280. }
  1281. #endif
  1282.  
  1283.  
  1284. /////////////////////////////////////////////////////////////////////////////
  1285.  
  1286. #ifdef AFX_CMNCTL_SEG
  1287. #pragma code_seg(AFX_CMNCTL_SEG)
  1288. #endif
  1289.  
  1290. #ifndef _AFX_ENABLE_INLINES
  1291.  
  1292. static const char _szAfxWinInl[] = "afxcmn.inl";
  1293. #undef THIS_FILE
  1294. #define THIS_FILE _szAfxWinInl
  1295. #define _AFXCMN_INLINE
  1296. #include "afxcmn.inl"
  1297.  
  1298. #endif //_AFX_ENABLE_INLINES
  1299.  
  1300. /////////////////////////////////////////////////////////////////////////////
  1301.  
  1302. #ifdef AFX_INIT_SEG
  1303. #pragma code_seg(AFX_INIT_SEG)
  1304. #endif
  1305.  
  1306. WCE_DEL IMPLEMENT_DYNAMIC(CDragListBox, CListBox)
  1307. IMPLEMENT_DYNAMIC(CSpinButtonCtrl, CWnd)
  1308. IMPLEMENT_DYNAMIC(CSliderCtrl, CWnd)
  1309. IMPLEMENT_DYNAMIC(CProgressCtrl, CWnd)
  1310. WCE_DEL IMPLEMENT_DYNAMIC(CComboBoxEx, CComboBox)
  1311. IMPLEMENT_DYNAMIC(CHeaderCtrl, CWnd)
  1312. WCE_DEL IMPLEMENT_DYNAMIC(CHotKeyCtrl, CWnd)
  1313. WCE_DEL IMPLEMENT_DYNAMIC(CAnimateCtrl, CWnd)
  1314. IMPLEMENT_DYNAMIC(CTabCtrl, CWnd)
  1315. IMPLEMENT_DYNAMIC(CTreeCtrl, CWnd)
  1316. IMPLEMENT_DYNAMIC(CListCtrl, CWnd)
  1317. #if !defined(_WIN32_WCE_NO_CONTROLBARS)
  1318. IMPLEMENT_DYNAMIC(CToolBarCtrl, CWnd)
  1319. IMPLEMENT_DYNAMIC(CStatusBarCtrl, CWnd)
  1320. #endif // _WIN32_WCE_NO_CONTROLBARS
  1321. IMPLEMENT_DYNCREATE(CImageList, CObject)
  1322.  
  1323. #if !defined(_WIN32_WCE)
  1324. IMPLEMENT_DYNCREATE(CTempImageList, CImageList);
  1325. #endif // _WIN32_WCE
  1326.  
  1327. #ifndef _AFX_NO_RICHEDIT_SUPPORT
  1328. IMPLEMENT_DYNAMIC(CRichEditCtrl, CWnd)
  1329. #endif
  1330.  
  1331. #if !defined(_WIN32_WCE)
  1332. #pragma warning(disable: 4074)
  1333. #pragma init_seg(compiler)
  1334. IMPLEMENT_FIXED_ALLOC(CTempImageList, 64);
  1335. #endif // _WIN32_WCE
  1336.  
  1337. /////////////////////////////////////////////////////////////////////////////
  1338.